#include "aabb.h"

#include "../math/quat.h"
#include "../math/vec3.h"

AABB::AABB() : _center(nullptr), _halfExtents(nullptr)
{
    this->_center = new Vec3(0, 0, 0);
    this->_halfExtents = new Vec3(0.5, 0.5, 0.5);
    this->_vertices[0].set(this->_center->getX() + this->_halfExtents->getX(), this->_center->getY() + this->_halfExtents->getY(), this->_center->getZ() + this->_halfExtents->getZ()); // 右上前
    this->_vertices[1].set(this->_center->getX() + this->_halfExtents->getX(), this->_center->getY() - this->_halfExtents->getY(), this->_center->getZ() + this->_halfExtents->getZ()); // 右下前
    this->_vertices[2].set(this->_center->getX() - this->_halfExtents->getX(), this->_center->getY() + this->_halfExtents->getY(), this->_center->getZ() + this->_halfExtents->getZ()); // 左上前
    this->_vertices[3].set(this->_center->getX() - this->_halfExtents->getX(), this->_center->getY() - this->_halfExtents->getY(), this->_center->getZ() + this->_halfExtents->getZ()); // 左下前
    this->_vertices[4].set(this->_center->getX() + this->_halfExtents->getX(), this->_center->getY() + this->_halfExtents->getY(), this->_center->getZ() - this->_halfExtents->getZ()); // 右上后
    this->_vertices[5].set(this->_center->getX() + this->_halfExtents->getX(), this->_center->getY() - this->_halfExtents->getY(), this->_center->getZ() - this->_halfExtents->getZ()); // 右下后
    this->_vertices[6].set(this->_center->getX() - this->_halfExtents->getX(), this->_center->getY() + this->_halfExtents->getY(), this->_center->getZ() - this->_halfExtents->getZ()); // 左上后
    this->_vertices[7].set(this->_center->getX() - this->_halfExtents->getX(), this->_center->getY() - this->_halfExtents->getY(), this->_center->getZ() - this->_halfExtents->getZ()); // 左下后
}
void AABB::setCenter(float x, float y, float z)
{
    this->_center->set(x, y, z);
}
Vec3 *AABB::getCenter()
{
    return this->_center;
}
void AABB::setHalfExtents(float x, float y, float z)
{
    this->_halfExtents->set(x, y, z);
}
Vec3 *AABB::getHalfExtents()
{
    return this->_halfExtents;
}

void AABB::transform(Vec3 *pos, Vec3 *scale, Quat *q)
{
    this->_center->set(pos->getX(), pos->getY(), pos->getZ());
    this->_halfExtents->set(0.5 * scale->getX(), 0.5 * scale->getY(), 0.5 * scale->getZ());
    this->_vertices[0].set(this->_center->getX() + this->_halfExtents->getX(), this->_center->getY() + this->_halfExtents->getY(), this->_center->getZ() + this->_halfExtents->getZ()); // 右上前
    this->_vertices[1].set(this->_center->getX() + this->_halfExtents->getX(), this->_center->getY() - this->_halfExtents->getY(), this->_center->getZ() + this->_halfExtents->getZ()); // 右下前
    this->_vertices[2].set(this->_center->getX() - this->_halfExtents->getX(), this->_center->getY() + this->_halfExtents->getY(), this->_center->getZ() + this->_halfExtents->getZ()); // 左上前
    this->_vertices[3].set(this->_center->getX() - this->_halfExtents->getX(), this->_center->getY() - this->_halfExtents->getY(), this->_center->getZ() + this->_halfExtents->getZ()); // 左下前
    this->_vertices[4].set(this->_center->getX() + this->_halfExtents->getX(), this->_center->getY() + this->_halfExtents->getY(), this->_center->getZ() - this->_halfExtents->getZ()); // 右上后
    this->_vertices[5].set(this->_center->getX() + this->_halfExtents->getX(), this->_center->getY() - this->_halfExtents->getY(), this->_center->getZ() - this->_halfExtents->getZ()); // 右下后
    this->_vertices[6].set(this->_center->getX() - this->_halfExtents->getX(), this->_center->getY() + this->_halfExtents->getY(), this->_center->getZ() - this->_halfExtents->getZ()); // 左上后
    this->_vertices[7].set(this->_center->getX() - this->_halfExtents->getX(), this->_center->getY() - this->_halfExtents->getY(), this->_center->getZ() - this->_halfExtents->getZ()); // 左下后

    // 旋转
    Vec3 min(0, 0, 0);
    Vec3 max(0, 0, 0);
    for (int i = 0; i < 8; ++i)
    {
        this->_vertices[i].rotate(q);
        if (i == 0)
        {
            min.set1(this->_vertices[i]);
            max.set1(this->_vertices[i]);
        }
        else
        {
            min.min(this->_vertices[i]);
            max.max(this->_vertices[i]);
        }
    }
    this->_halfExtents->set((max.getX() - min.getX()) * 0.5f, (max.getY() - min.getY()) * 0.5f, (max.getZ() - min.getZ()) * 0.5f);
}

AABB::~AABB()
{
    delete this->_center;
    delete this->_halfExtents;
    this->_center=nullptr;
    this->_halfExtents=nullptr;
}